﻿using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;

public abstract class ClientsManagerBase : IGameLifeCycle
{
    public const byte PingByte = 1;

    public IClientsManagerListener listener { get; set; }

    /// <summary>
    /// 所有客户端
    /// </summary>
    protected AtomDictionary<IPEndPointKey, Remote> m_ClientList = new AtomDictionary<IPEndPointKey, Remote>();
    public AtomDictionary<IPEndPointKey, Remote> clientList => m_ClientList;

    public struct IPEndPointKey
    {
        public string ip;
        public int port;

        public static IPEndPointKey GetIPEndPointKey(IPEndPoint iPEndPoint)
        {
#if MultiClientDebug
            return new IPEndPointKey() { ip = iPEndPoint.Address.ToString(), port = iPEndPoint.Port };
#else
            return new IPEndPointKey() { ip = iPEndPoint.Address.ToString() };
#endif
        }
    }

    /// <summary>
    /// 当前待分配的客户端ID
    /// </summary>
    protected long m_CurClientId;

    /// <summary>
    /// 监听Socket
    /// </summary>
    protected abstract ServerSocket socketServer { get; }

    public abstract void Start(int port, int maxConnectCount);

    /// <summary>
    /// 获取当前clientID
    /// </summary>
    /// <returns></returns>
    protected long GetCurClientId()
    {
        return System.Threading.Interlocked.Increment(ref m_CurClientId);
    }

    public void AddClient(IPEndPoint endPoint, Remote remote)
    {
        GameDebug.Log($"AddClient   ipEndPoint:{endPoint}  remote:{remote.clientId}");
        this.m_ClientList[IPEndPointKey.GetIPEndPointKey(endPoint)] = remote;
    }

    public virtual void RemoveClient(IPEndPoint endPoint)
    {
        this.m_ClientList.Remove(IPEndPointKey.GetIPEndPointKey(endPoint));
    }

    /// <summary>
    /// 添加登录用户
    /// </summary>
    /// <param name="userId"></param>
    /// <param name="_client"></param>
    public virtual void OnAddLoginedUser(long userId, Remote _client)
    {
#if MultiClientDebug
        //测试期间使用IP加端口来区分客户端，以能模拟一台电脑运行多个客户端
        IPEndPointKey iPEndPointKey = new IPEndPointKey();
        ///TODO. lock
        foreach(var client in m_ClientList.dictionary)
        {
            if(client.Value.userID == userId)
            {
                GameDebug.Log($"userId{userId} 移除旧连接 {client.Value.ipEndPoint} 准备替换为新连接：{_client.ipEndPoint}");
                iPEndPointKey = client.Key;
            }
        }
        if (iPEndPointKey.port > 0)
        {
            m_ClientList.Remove(iPEndPointKey);
        }
#endif
    }

    
    public virtual void Update(int frameCount)
    {

    }
} 

